package org.dromara.crawler.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;

import com.mongodb.client.gridfs.model.GridFSFile;

import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.crawler.domain.bo.DataCollectionBo;

import org.dromara.crawler.domain.bo.ImageQueryBo;
import org.dromara.crawler.domain.vo.DataSource;
import org.dromara.crawler.mongo.mongodomain.CNN;

import org.dromara.crawler.mongo.mongodomain.Wiki;
import org.dromara.crawler.mongo.mongodomain.XinHuaNet;
import org.dromara.crawler.mongo.mongoservice.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLConnection;
import java.util.*;


/**
 * 数据管理模块
 */
@Slf4j
@RestController
@RequestMapping("/dataManager")
public class DataManagerController {
    @Autowired
    private XinHuaNetService xinHuaNetService;
    @Autowired
    private CNNService cnnService;
    @Autowired
    private WikiService wikiService;
    @Autowired
    private KnowledgeTargetService knowledgeTargetService;
    @Autowired
    private KnowledgeEventService knowledgeEventService;
    @Autowired
    private HotspotEventService hotspotEventService;


    private GridFsTemplate xinHuaGridFsTemplate;
    private GridFsTemplate cnnGridFsTemplate;
    private GridFsTemplate wikiGridFsTemplate;

    public DataManagerController(
        @Qualifier("xinHuaGridFsTemplate") GridFsTemplate xinHuaGridFsTemplate,
        @Qualifier("cnnGridFsTemplate") GridFsTemplate cnnGridFsTemplate,
        @Qualifier("wikiGridFsTemplate") GridFsTemplate wikiGridFsTemplate
    ) {
        this.xinHuaGridFsTemplate = xinHuaGridFsTemplate;
        this.cnnGridFsTemplate = cnnGridFsTemplate;
        this.wikiGridFsTemplate = wikiGridFsTemplate;
    }

    /**
     * 数据管理查询
     */
    @GetMapping("/queryByPage")
    public R<IPage<DataSource>> queryByPage(DataCollectionBo dataCollectionBo,
                                            @RequestParam(defaultValue = "1") Integer pageNum,
                                            @RequestParam(defaultValue = "10") Integer pageSize) {
        try {
            PageQuery pageQuery = new PageQuery(pageSize, pageNum);
            return R.ok(xinHuaNetService.queryByPage(dataCollectionBo, pageQuery));
        } catch (Exception e) {
            log.error("查询数据失败，原因：" + e.getMessage(), e);
            return R.fail(e.getMessage());
        }
    }

    /**
     * 新华网数据查询
     */
    @GetMapping("/queryXinHuaById")
    public R<XinHuaNet> queryXinHuaById(@RequestParam String id) {
        try {
            return R.ok(xinHuaNetService.queryById(id));
        } catch (Exception e) {
            log.error("查询数据失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * CNN网数据查询
     */
    @GetMapping("/queryCnnById")
    public R<CNN> queryCnnById(@RequestParam String id) {
        try {
            return R.ok(cnnService.queryById(id));
        } catch (Exception e) {
            log.error("查询数据失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * Wiki根据id查询
     */
    @GetMapping("/queryWikiById")
    public R<Wiki> queryWikiById(@RequestParam String id) {
        try {
            return R.ok(wikiService.queryById(id));
        } catch (Exception e) {
            log.error("查询数据失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * Wiki查询全部
     */
    @GetMapping("/getAll")
    public R<List<Wiki>> getAll() {
        try {
            return R.ok(wikiService.getAll());
        } catch (Exception e) {
            log.error("获取失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }

    }

    /**
     * Wiki按照条件查询
     */
    @GetMapping("/queryWikiByCondition")
    public R<List<Wiki>> queryWikiByCondition(DataCollectionBo bo) {
        try {
            return R.ok(wikiService.queryByCondition(bo));
        } catch (Exception e) {
            log.error("Wiki 条件查询失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    @GetMapping("/getXinHuaImage")
    public void getXinHuaImage(@RequestParam String imageId, HttpServletResponse response) {
        getOutputStream(imageId, response, xinHuaGridFsTemplate);
    }

    @GetMapping("/getCnnImage")
    public void getCnnImage(@RequestParam String imageId, HttpServletResponse response) {
        getOutputStream(imageId, response, cnnGridFsTemplate);
    }

    @GetMapping("/getWikiImage")
    public void getWikiImage(@RequestParam String imageId, HttpServletResponse response) {
        getOutputStream(imageId, response, wikiGridFsTemplate);
    }

    /**
     * 获取图片资源
     *
     * @param imageQueryBo
     * @param response
     */
    @GetMapping("/getImage")
    private void getOutputImages(ImageQueryBo imageQueryBo, HttpServletResponse response) {
        if (imageQueryBo.getSource().equals("1")) {
            getOutputStream(imageQueryBo.getImageId(), response, xinHuaGridFsTemplate);
        } else if (imageQueryBo.getSource().equals("2")) {
            getOutputStream(imageQueryBo.getImageId(), response, cnnGridFsTemplate);
        } else if (imageQueryBo.getSource().equals("3")) {
            getOutputStream(imageQueryBo.getImageId(), response, wikiGridFsTemplate);
        }
    }


    private void getOutputStream(String imageId, HttpServletResponse response, GridFsTemplate gridFsTemplate) {
        try {
            // 查询 GridFS 文件
            GridFSFile file = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(new ObjectId(imageId))));
            if (file == null) {
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                response.setContentType("text/plain");
                response.getWriter().write("Image not found.");
                return;
            }
            // 获取文件资源
            GridFsResource resource = gridFsTemplate.getResource(file);
            // 尝试从 metadata 获取 contentType，否则根据文件名后缀推断
            String contentType = null;
            if (file.getMetadata() != null && file.getMetadata().get("_contentType") != null) {
                contentType = file.getMetadata().get("_contentType").toString();
            } else {
                contentType = URLConnection.guessContentTypeFromName(resource.getFilename());
            }
            if (contentType == null) {
                contentType = "application/octet-stream"; // fallback
            }

            // 设置响应头
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "inline; filename=\"" + resource.getFilename() + "\"");
            // 输出图片内容
            try (InputStream is = resource.getInputStream(); OutputStream os = response.getOutputStream()) {
                StreamUtils.copy(is, os); // 更简洁
            }
        } catch (Exception e) {
            // 统一错误处理（返回状态码 + 消息）
            try {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.setContentType("text/plain");
                response.getWriter().write("读取图片异常：" + e.getMessage());
            } catch (IOException ioException) {
                // 忽略
            }
        }
    }


    //知识库数据统计
    @GetMapping("/countAll")
    public R<Long> countAll() {
        try {
            // 统计Target知识库数据
            Long originalCount = xinHuaNetService.countAll(knowledgeTargetService);

            // 统计Event知识库数据
            Long eventCount = xinHuaNetService.countAll(knowledgeEventService);

            // 返回总和
            return R.ok(originalCount + eventCount);
        } catch (Exception e) {
            log.error("获取失败，原因：" + e.getMessage(), e);
            return R.fail("知识库数据统计失败：" + e.getMessage());
        }
    }

    /**
     * 热点事件数据统计
     */
    @GetMapping("/hotspot-stats")
    public R<Long> getHotspotEventStats() {
        try {
            Long count = hotspotEventService.count();
            return R.ok(count);
        } catch (Exception e) {
            log.error("获取热点事件统计失败，原因：" + e.getMessage(), e);
            return R.fail("热点事件统计失败：" + e.getMessage());
        }
    }




    /**
     * 站点数据统计+知识库数据统计+热点
     */
    @GetMapping("/combined-stats")
    public R<Map<String, Long>> getCombinedStats(@RequestParam(required = false) String keyword) {
        try {
            return R.ok(xinHuaNetService.getCombinedStats(knowledgeTargetService, knowledgeEventService, keyword));
        } catch (Exception e) {
            log.error("获取统计失败，原因：" + e.getMessage(), e);
            return R.fail("数据统计失败：" + e.getMessage());
        }
    }


    /**
     * 获取月度统计数据
     */

    @GetMapping("/monthly-stats")
    public R<Map<String, Long>> getMonthlyStats() {
        try {
            return R.ok(xinHuaNetService.getMonthlyStats());
        } catch (Exception e) {
            log.error("获取月度统计数据失败，原因：" + e.getMessage(), e);
            return R.fail("月度统计失败：" + e.getMessage());
        }
    }

    /**
     * 获取月度统计数据2
     */

    @GetMapping("/getMonthStatistics")
    public R<Object> getMonthStatistics(@RequestParam(required = false) String keyword) {
        try {
            Object monthStatistics = xinHuaNetService.getMonthStatistics(keyword);
            return R.ok(monthStatistics);
        } catch (Exception e) {
            log.error("获取月度统计数据失败", e);
            return R.fail("获取月度统计数据失败: " + e.getMessage());
        }
    }

}
